/**
 * 事件处理
 */
patchProps(el, key, prevValue, nextValue) {
    if (/^on/.test(key)) {
        // 获取为该元素伪造的事件处理函数 invoker
        let invoker = el._vei
        const name = key.slice(2).toLowerCase()
        if (nextValue) {
            if (!invoker) {
                // 如果没有 invoker，则将一个伪造的 invoker 缓存到 el._vei 中
                // vei 是 vue event invoker 的首字母缩写
                invoker = el._vei = (e) => {
                    // 当伪造的事件处理函数执行时，会执行真正的事件处理函数
                    invoker.value(e)
                }
                // 将真正的事件处理函数赋值给 invoker.value
                invoker.value = nextValue
                // 绑定 invoker 作为事件处理函数
                el.addEventListener(name, invoker)
            } else {
                // 如果 invoker 存在，意味着更新，并且只需要更新 invoker.value 的值即可
                invoker.value = nextValue
            }
        } else if (invoker) {
            // 新的事件绑定函数不存在，且之前绑定的 invoker 存在，则移除绑定
            el.removeEventListener(name, invoker)
        }
    } else if (key === 'class') {
        // 省略部分代码
    } else if (shouldSetAsProps(el, key, nextValue)) {
        // 省略部分代码
    } else {
        // 省略部分代码
    }
}


// 多个不同事件时
patchProps(el, key, prevValue, nextValue) {
    if (/^on/.test(key)) {
        // 定义 el._vei 为一个对象，存在事件名称到事件处理函数的映射
        const invokers = el._vei || (el._vei = {})
        //根据事件名称获取 invoker
        let invoker = invokers[key]
        const name = key.slice(2).toLowerCase()
        if (nextValue) {
            if (!invoker) {
                // 将事件处理函数缓存到 el._vei[key] 下，避免覆盖
                invoker = el._vei[key] = (e) => {
                    invoker.value(e)
                }
                invoker.value = nextValue
                el.addEventListener(name, invoker)
            } else {
                invoker.value = nextValue
            }
        } else if (invoker) {
            el.removeEventListener(name, invoker)
        }
    } else if (key === 'class') {
        // 省略部分代码
    } else if (shouldSetAsProps(el, key, nextValue)) {
        // 省略部分代码
    } else {
        // 省略部分代码
    }
}

// 同一个属性上有多个事件
patchProps(el, key, prevValue, nextValue) {
    if (/^on/.test(key)) {
        const invokers = el._vei || (el._vei = {})
        let invoker = invokers[key]
        const name = key.slice(2).toLowerCase()
        if (nextValue) {
            if (!invoker) {
                invoker = el._vei[key] = (e) => {
                    // 如果 invoker.value 是数组，则遍历它并逐个调用事件处理函数
                    if (Array.isArray(invoker.value)) {
                        invoker.value.forEach(fn => fn(e))
                    } else {
                        // 否则直接作为函数调用
                        invoker.value(e)
                    }
                }
                invoker.value = nextValue
                el.addEventListener(name, invoker)
            } else {
                invoker.value = nextValue
            }
        } else if (invoker) {
            el.removeEventListener(name, invoker)
        }
    } else if (key === 'class') {
        // 省略部分代码
    } else if (shouldSetAsProps(el, key, nextValue)) {
        // 省略部分代码
    } else {
        // 省略部分代码
    }
}